package io.esirong.util;

public class Smooth {

    //    当初速度和加速度同向时 距离S=初速度V*时间t+1/2at^2
//    当初速度和加速度反向的 S=V*T-1/2at^2
    public static double culS() {
        double v = 0;
        double t = 0;
        double a = 0;
        double s = v * t + a * t * t / 2;
        return s;

    }

    static int sActual = 0;


    public static void main(String[] args) {
        System.out.println("000");

        new Thread(new Runnable() {
            @Override
            public void run() {
                double sFake = 0;
                while (sActual < 100) {

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("发出:" + sActual);
                    update(sActual);
                    sActual += Math.random() * 100;
                }

            }
        }).start();

    }

    static double v = 0.01;
    static double t = 0.2;
    static double a = 0;
    static double total2 = 0;
    static Thread thread;

    public static void update(int actual) {
        sActual = actual;
        a = 0;
        if (done) {
            thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    total2 = addS(actual);
                }
            });
            thread.start();
            done = false;
        }

    }

    //动态插值平滑处理算法（2次幂）(模拟冲刺一段距离）
    public static double addS(int actual) {
        //#标准速度

        double sFake = total2;//模拟位置

        //差距
        double dS = sActual - sFake;
        // a++;
        a = 0;
        System.out.println("开始：" + a);
        double sprintS = 0;//一次冲刺计算开始位
        while (sActual >= sFake) {

            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            send(sActual, sFake, v);
            System.out.print(" a速:" + String.format("%.2f", a));
            if (sprintS < (dS * 9 / 10)) {
                //加速
                if (a < 0) {
                    a = 0;
                }
                a += 0.1;
                System.out.print(" 加速:" + String.format("%.2f", a));

            } else {
                //减速
                if (a > 0) {
                    a = 0;
                }
                a -= 0.5;
                System.out.print(" 减速:" + String.format("%.2f", a));
                if (v <= 0) {
                    //修正一次冲开始，冲刺距离段
                    sprintS = 0;
                    dS = sActual - sFake;
                }
            }

            v = v + (a * t) / 2;//#调整速度
            v = v > 0 ? v : 0;//#速度修正(不能为负)
            double s = v * t;//#计算行进距离
            sprintS += s;//#冲刺段距离
            sFake += s;

            System.out.println("sFake=" + sFake);
            //停止
            if (sFake + 0.5 > sActual && v <= 0.05) {
                stop(sActual, sFake, v);
                break;
            }
            //无限接近的终止值0.1
            if (sActual <= sFake && v > 0) {
                crash(sActual, sFake, v);
            }
        }
        done = true;
        return sFake;
    }

    static boolean done = true;

    private static void send(double sActual, double sFake, double v) {
        System.out.print(" 进入:" + String.format("%.2f", sActual));
        System.out.print(" 进入:" + String.format("%.2f", sFake));
        System.out.print(" v:" + String.format("%.2f", v));
    }

    private static void stop(double sActual, double sFake, double v) {
        System.out.print(" 进入:" + String.format("%.2f", sActual));
        System.out.print(" 进入:" + String.format("%.2f", sFake));
        System.out.print(" v:" + String.format("%.2f", v));

    }

    private static void crash(double sActual, double sFake, double v) {
        System.out.print("进入:" + sActual + ":" + sFake);
        System.out.print("v速：" + v);
        System.out.println("撞上了");
    }

    private static double sprintA(double sprintS, double dS, double a) {
        if (sprintS < (dS * 2 / 4)) {
            //加速
            if (a < 0) {
                a = 0;
            }
            a += 0.1;
            System.out.print("加速：" + a);

        } else {
            //减速
            if (a > 0) {
                a = 0;
            }
            a -= 0.5;
            System.out.print("减速：" + a);

        }
        return a;

    }

    private static double sprintS(double v, double a, double t) {
        double result = 0;
        v = v + (a * t) / 2;//#调整速度
        v = v > 0 ? v : 0;//#速度修正(不能为负)
        double s = v * t;//#计算行进距离
        return result;
    }
}
